package DAL;

import java.util.*;
import java.io.*;

import DTO.*;

/**
 * Classe responsável pelo gerenciamento físico, dos registros de jogos.
 *
 * @author (R. Soares)
 * @version (1.0 - 26.04.2010)
 */
public class JogoDAL extends ArquivoControleDAL
{
    // Variáveis de Instância --------------------------------------------------*

    // Lista de jogos salvos.
    HashMap _listaJogos;

    // Contrutores -------------------------------------------------------------- *
    /**
     * O construtor da classe informa o nome do arquivo  de registro de jogos que
     * será lido.
     */
    public JogoDAL()
    {
        // Informa o nome do aquivo de registro de jogos.
        super("registrojogo");

        obterJogosSalvos();
    }

    // Métodos ---------------------------------------------------------------------*

    /**
     *  Metodo que Grava um novo registro de jogo ou altera um registro existente.
     */
    public void gravarJogo(JogoDTO jogo)
    {
          if( _listaJogos == null)
                _listaJogos = new HashMap();

         if( !_listaJogos.containsKey( jogo.getJogador() ) )
         {
             _listaJogos.put( jogo.getJogador(), jogo);

             gravarJogos();
          }

          else
          {
                _listaJogos.remove( jogo.getJogador() );
                _listaJogos.put( jogo.getJogador(), jogo);
                gravarJogos();
          }

    }

    /**
     *  Metodo que remove um registro de jogo do arquivo
     */
    public void removeJogo(String identificadorJogo)
    {
           if( !(_listaJogos == null) )
           {
                if( _listaJogos.containsKey( identificadorJogo ) )
                {
                    _listaJogos.remove( identificadorJogo );
                    gravarJogos();
                }
           }
    }

    /**
     *  Metodo que grava a atual lista de jogos em arquivo.
     */
    private void gravarJogos()
    {
           String linhaArquivo = null;

           ArrayList listaJogos = new ArrayList();

           Iterator it = _listaJogos.keySet().iterator();

           JogoDTO jogo = null;

           // informações para consulta de dados de meteoros
           ListaMeteoros listaMeteoros = null;
           MeteoroDTO meteoro =  null;
           int [] listaChaveMeteoros;


           while (it.hasNext() )
           {
               jogo = (JogoDTO) _listaJogos.get( (String) it.next() );

               linhaArquivo =   jogo.getJogador() ;

               linhaArquivo =  linhaArquivo + " " + jogo.getFase();

               linhaArquivo =  linhaArquivo + " " +  jogo.getEscore();

               linhaArquivo =  linhaArquivo + " " +  jogo.getChancesJogo();


               // Consulta dos dados dos meteoros

               listaMeteoros = jogo.getListaMeteoros();

               listaChaveMeteoros = listaMeteoros.retornaChaveMeteoros();

               for( int i = 0; i  <  listaMeteoros.getQuantidadeMeteoros(); i ++ )
               {
                   meteoro = listaMeteoros.retornaMeteoro( listaChaveMeteoros [i] );
                   linhaArquivo = linhaArquivo + " " +  meteoro.getPontosResistencia();
               }

                listaJogos.add ( linhaArquivo );
                linhaArquivo = null;
           }

           escreverArquivo(listaJogos);

    }

    /*
     * Os seguintes métodos são empregados na consulta de Jogos lidos do arquivo,
     */

    /**
     *  Metodo que retorna um objeto JogoDTO, especificado pelo seu identificador.
     *
     * @return  JogoDTO
     */
    public JogoDTO selecionarPorID(String identificador)
    {
        if(  _listaJogos != null )
        {
                return (JogoDTO) _listaJogos.get(identificador);
         }

         return null;
    }

    /**
     *  Metodo que retorna a lista de jogos salvos, gravados em arquivo.
     *
     * @return  HashMap : _listaJogos.
     */
    public HashMap getListaTodos()
    {
        return _listaJogos;
    }

    /*
     * Os seguintes métodos são empregados na leitura dos dados gravados em arquivo
     */

    /**
     *  Metodo que realiza a leitura dos dados do arquivo de jogos para obter os jogos
     *  salvos.
     */
    private void obterJogosSalvos()
    {
        ArrayList linhasArquivo = lerArquivo();
        JogoDTO jogoLido = null;

        if( ! linhasArquivo.isEmpty() )
        {
            _listaJogos = new HashMap();

            Iterator it = linhasArquivo.iterator();

            while ( it.hasNext() )
            {
                jogoLido =  gerarJogo( (String) it.next() );
                _listaJogos.put(jogoLido.getJogador(), jogoLido);
            }

        }

     } // fim obterJogosSalvos

    /**
     *  Metodo que retorna um objeto JogoDTO gerado com os dados do registro da linha
     *  informada.
     *
     * @param  linhaArquivio : linha do arquivo a ser lida.
     * @return  JogoDTO : Jogo Gerado.
     */
    private JogoDTO gerarJogo(String linhaArquivo)
    {
        // Dados para geração de objeto JogoDTO
        String nomeJogador = null;
        int fase = 0;
        int escore = 0;
        int chances = 0;
        int resistenciaMeteoro = 0;
        MeteoroDTO meteoro = null;
        ListaMeteoros listaMeteoros = new ListaMeteoros();
        int chaveMeteoro = 0;

        // Controle da posicao atual lida do registro
        int posicaoAtualFrase = 0;

        // linharArquivo com palavras serializadas
        ArrayList linhaSerial = new ArrayList();

        // posição da palavra na sequencia da frase.
        int posicaoPalavra = 0;

        // palavra retirada da frase
        String palavra =  null;

        try{

                while (posicaoAtualFrase < linhaArquivo.length() + 1)
                {
                        palavra = lerPalavra( linhaArquivo, posicaoAtualFrase);

                        linhaSerial.add(posicaoPalavra, palavra);

                        posicaoAtualFrase = posicaoAtualFrase + palavra.length() + 1;

                        posicaoPalavra ++;
                } // fim while


                if( linhaSerial.size() < 5 )
                        throw new NullPointerException();

                else
                {
                    nomeJogador = (String) linhaSerial.get(0);

                    fase = obterValorInteiro( (String) linhaSerial.get(1) );

                    escore = obterValorInteiro( (String) linhaSerial.get(2) );

                    chances = obterValorInteiro( (String) linhaSerial.get(3) );

                    posicaoPalavra = 4;

                    while (posicaoPalavra < linhaSerial.size() )
                    {
                            resistenciaMeteoro = obterValorInteiro( (String) linhaSerial.get(posicaoPalavra) );

                            meteoro = new MeteoroDTO (chaveMeteoro,resistenciaMeteoro );

                            listaMeteoros.setMeteoro(meteoro);

                            chaveMeteoro = chaveMeteoro +1;

                            posicaoPalavra++;

                    } // fim while

               } // fim else
         }

         catch(NullPointerException e) {
                  System.out.println("Arquivo REGISTROJOGO.CTR corrompido");
         }

        return new JogoDTO(nomeJogador, fase, escore, chances, listaMeteoros);

    } // fim gerarJogo


    /**
     *  Metodo que retorna uma palavra entre dois marcadores de espaço do registro de arquivo
     *
     * @param  linhaArquivio : linha do arquivo a ser lida.
     * @param  posicaoAtual : posicao do inicio da leitura.
     * @return  String : palavra lida.
     */
    private String lerPalavra(String linhaArquivo, int posicaoAtual)
    {
        String linhaLida = linhaArquivo + " ";
        int posicao = posicaoAtual;

        while (! linhaLida.substring(posicao, posicao + 1).equals(" ") )
        {
            posicao++;
        }

        return linhaArquivo.substring(posicaoAtual, posicao);

    } // fim lerPalavra
}
